#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <string>
#include <memory>

class WaveReader
{
public:
    WaveReader();
    ~WaveReader();

    int Open(const char *filepath);
    void Close();
    std::size_t Read(char *data, std::size_t len);
    int GetAudioInfo(uint32_t &sample_rate, uint16_t &channel_count, uint16_t &bit_per_sample) const;

private:
    ::FILE *file_;
    std::string filepath_;
    std::shared_ptr<char[]> audio_data_;
    uint32_t file_size_;
    uint32_t pos_;

    uint32_t sample_rate_;
    uint16_t channel_count_;
    uint16_t bit_per_sample_;
};

// only work for lettle endian
class WaveWriter
{
public:
    WaveWriter();
    ~WaveWriter();

    int SetAudioInfo(uint32_t sample_rate, uint16_t channel_count, uint16_t bit_per_sample);
    int Open(const char *filepath);
    void Close();
    int Write(const char *data, std::size_t len, std::size_t nmeb);

private:
    void Reset();
    int WriteHeader();
    int ConstructWaveHeader(std::shared_ptr<char[]> &wave_header);

    ::FILE *file_;
    std::string filepath_;
    uint32_t file_size_;

    uint32_t sample_rate_;
    uint16_t channel_count_;
    uint16_t bit_per_sample_;
};